
#include "hi_wifi_api.h"
#include "lwip/ip_addr.h"
#include "lwip/netifapi.h"
#include "lwip/sockets.h"
#include <stdio.h>

#include "iot_gpio.h"

#include <unistd.h>
#include "ohos_init.h"
#include "cmsis_os2.h"
#include "cJSON.h"

#include "hi_gpio.h"
#include "hi_io.h"
#include "hi_i2c.h"

#define LED_TEST_GPIO 9 //for hispark_pegasus

#define MY_PORT       3861
#define SERVER_PORT   3861

char g_recvline[1024];
int g_sockfd;

void cotrl_handle(char *recvline,int ret)
{
    printf("recv is %s\r\n",recvline);

    if(0 == strcmp("led on",recvline))
    {
        //开灯
        IoTGpioSetOutputVal(LED_TEST_GPIO,1);
    }
     
    if(0 == strcmp("led off",recvline))
    {
        //关灯
        IoTGpioSetOutputVal(LED_TEST_GPIO,0);
    }
}

//用于接收的线程
void udp_thread(void *pdata)
{
    int ret;
    struct sockaddr_in servaddr;

    pdata = pdata;

    while(1)
    {
        struct sockaddr_in addrClient;
        int sizeClientAddr = sizeof(struct sockaddr_in);
        
        memset(recvline,sizeof(recvline),0);
        //接收数据的api接口
        ret = recvfrom(g_sockfd,recvline,sizeof(recvline),0,(struct sockaddr*)&addrClient,(socklen_t*)&sizeClientAddr);

        if(ret>0)
        {
            char *pClientIP = inet_ntoa(addrClient.sin_addr);
            //打印对方的ip地址和端口号
            printf("%s-%d(%d) says:%s\n",pClientIP,ntohs(addrClient.sin_port),addrClient.sin_port,recvline);
            //对数据进行处理
            cotrl_handle(recvline,ret);
        }
    }
}


void start_udp_thread(void)
{
    osThreadAttr_t attr;
    
    attr.name = "wifi_config_thread";
    attr.attr_bits = 0U;
    attr.cb_mem = NULL;
    attr.cb_size = 0U;
    attr.stack_mem = NULL;
    attr.stack_size = 2048;
    attr.priority = 36;

    if (osThreadNew((osThreadFunc_t)udp_thread, NULL, &attr) == NULL) {
        printf("[upd_demo] Falied to create wifi_sta_demo!\n");
    }
}

void aht20_init(void)
{
    ssize_t retval = 0;

    hi_io_set_func(HI_IO_NAME_GPIO_13,HI_IO_FUNC_GPIO_13_I2C0_SDA);
    hi_io_set_func(HI_IO_NAME_GPIO_14,HI_IO_FUNC_GPIO_14_I2C0_SCL);

    hi_i2c_init(HI_I2C_IDX_0,400*1000);

    retval = AHT20_Calibrate();
    printf("AHT20_Calibrate: %d\r\n",retval);
}

void udp_demo(void)
{
    cJSON *root;
    char result[20];//上传的温湿度数据
    int ret;
    float temp=0.0,humi=0.0;

    ssize_t retval = 0;

    //温湿度传感器初始化
    aht20_init();

    //创建udp的socket
    g_sockfd = socket(PF_INET,SOCK_DGRAM,0);
    //server ip port
    struct sockaddr_in servaddr;
    struct sockaddr_in client_addr;
    char sendline[100] = "hello world";

    bzero(&servaddr,sizeof(servaddr));
    servaddr.sin_family = AF_INET;
    //绑定服务器端口
    servaddr.sin_port = htons(SERVER_PORT);
    servaddr.sin_addr.s_addr = inet_addr("255.255.255.255");
    //my ip port (bind),也可以不绑定本地port，那么本地发送的port就是随机的。

    bzero(&client_addr,sizeof(client_addr));
    client_addr.sin_family = AF_INET;
    client_addr.sin_port = htons(MY_PORT);
    client_addr.sin_addr.s_addr = htonl(INADDR_ANY);
    //client发出的udp包就是从这个port发出

    if(bind(g_sockfd,(struct sockaddr *)&client_addr,sizeof(client_addr))<0)
    {
        printf("video rtcp bine ret < 0\n");
    }

    //使能广播包
    int opt=1;
    ret = setsockopt(g_sockfd,SOL_SOCKET,SO_BROADCAST,&opt,sizeof(opt));


    //初始化GPIO
    IoTGpioInit(LED_TEST_GPIO);

    //设置输出
    IoTGpioSetDir(LED_TEST_GPIO,IOT_GPIO_DIR_OUT);

    start_udp_thread();

    while (1)
    {
        retval = AHT20_StartMeasure();
        printf("AHT20_StartMeasure: %d\r\n", retval);

        retval = AHT20_GetMeasureResult(&temp, &humi);
        printf("AHT20_GetMeasureResult: %d, temp = %.2f, humi = %.2f\r\n", retval, temp, humi);

        memset(result,0,sizeof(result));
        //按着温湿度的格式进行格式化输出到数组
        sprintf(result,"%.2f:%.2f",temp,humi);

        retval = sendto(g_sockfd,result,strlen(result),0,(struct sockaddr *)&servaddr,sizeof(servaddr));
        if(retval < 0){
            printf("sendto failed\r\n");
        }
        printf("send UDP message {%s} %ld done!\r\n",result,ret);

        sleep(3);
    }
    
}